# Transform the format of an input C++ head file to SWIG interface file
# Date: 2005-04-18 13:31

import sys
import string

# judge whether the line is comments or not: 
def IsComments(line):
	if (line[0] == '/'):
		if (line[1] == '/'):
			return 1
		elif (line[1] == '*'):
			return 2
        else:
			return 0

# skip multi-line comments:
def SkipMulLine(fd):
	line = fd.readline()
	try:
		string.index(line, "*/")
	except ValueError:
		SkipMulLine(fd)
	else:
		return fd

# judge whether the line include the key-word:
def IsKey(line, key):
	try:
		string.index(line, key)
	except ValueError:
		return 0
	else:
		return 1

# Skip comment-lines, move the file pointer to the last line of comments:
def SkipComments(line, fs):
	com_type = IsComments(line)
	if (com_type == 1):
		return 1
	elif (com_type == 2):
		SkipMulLine(fs)
		return 1
	else:
		return 0

# Skip the comments beginning from half of a line, return effective words:
def SkipHalfComments(line, fs):
	try:
		position = string.index(line, "//")
	except ValueError:
		try:
			position = string.index(line, "/*")
		except ValueError:
			return line
		else:
			SkipMulLine(fs)
			return line[0:position] + "\n"
	else:
		return line[0:position] + "\n"

# To deal with the class defination, copy public parts:
def CopyClass(line, fs, fd):
	fd.writelines(line)
	class_finish = 0
	while (class_finish == 0):
		line = fs.readline()
		renum = SkipComments(line, fs)
		if (renum != 1):
			line = SkipHalfComments(line, fs)
			try:
				string.index(line, "protected:")
			except ValueError:
				pass
			else:
				break
			try:
				string.index(line, "private:")
			except ValueError:
				pass
			else:
				break
			try:
				string.index(line, "};")
			except ValueError:
				pass
			else:
				class_finish = 1
				break
			fd.writelines(line)
	while (class_finish != 1):
		line = fs.readline()
		renum = SkipComments(line, fs)
		if (renum != 1):
			line = SkipHalfComments(line, fs)
			try:
				string.index(line, "};")
			except ValueError:
				pass
			else:
				class_finish = 1
	fd.writelines("};\n")

# add a '%{,%}' tag to the line: 
def AddSwigTag(line, fd):
	fd.writelines("%{\n")
	fd.writelines(line)
	fd.writelines("%}\n")

# main transform start here:

# open(file.h)
try:
	f_h = open(sys.argv[1], "r")
except IOError:
	print "Trans Error: " + "No such file or directory: " + sys.argv[1]
	sys.exit()

# extract module_name;
try:
	module_name = sys.argv[1][:-2]
	print "module name is: " + module_name
	module_file_name = module_name + ".i"
	print "generated interface name is: " + module_file_name
except IndexError:
	print "Trans Error: " + "please input the head file name!"
	sys.exit()

# open (module_name.i), writeline(%module module_name)
f_i = open(module_file_name, "w+")
f_i.writelines("%module " + module_name )
f_i.writelines("\n")
f_i.writelines("%{\n")
f_i.writelines("#include \"" + sys.argv[1] + "\"\n")
f_i.writelines("%}\n")

# read line by line, transform according to its type:
h_line = f_h.readline()
while h_line:
	renum = SkipComments(h_line, f_h)
	if (renum != 1):
		h_line = SkipHalfComments(h_line, f_h)
		if (IsKey(h_line, "#include") == 1):
			AddSwigTag(h_line, f_i)
		elif (IsKey(h_line, "typedef") == 1):
			AddSwigTag(h_line, f_i)
		elif (IsKey(h_line, "class") == 1):
			CopyClass(h_line, f_h, f_i)
		else:
			f_i.writelines(h_line)
	h_line = f_h.readline()

f_h.close()
f_i.close()


